大家好,這裡是鐵匠史密斯~
時間過得真快,不知不覺我們已經來到鐵人賽的第 24 天!
昨天角色的前進與後退剛完成,今天就讓我們停下來小小喘口氣,
來回顧一下 Day 11 ~ Day 23 的進度,也順便整理一下目前遊戲的樣貌
這段時間,我們從「第一道光」開始推導,逐步掌握了光線的行進方式:
fDistanceToWall
模擬光一步一步往前走接著,我們讓「距離」影響到「牆壁在畫面上的高度」。
這裡的核心公式就是:
int nCeiling = (float)(nScreenHeight / 2.0) - nScreenHeight / ((float)fDistanceToWall);
int nFloor = (float)(nScreenHeight / 2.0) + nScreenHeight / ((float)fDistanceToWall);
結果很直觀:
越近的牆 -> fDistanceToWall
越小 → 牆壁越高
越遠的牆 -> fDistanceToWall
越大 → 牆壁越矮
這段推導特地借用了光學的 針孔成像定理 來解釋,
牆壁就像物體,螢幕就像底片(人眼視網膜),
所以牆高與距離成反比 H = h * 1 / d ~ 1/d
。
光線與牆高確立之後,我們開始開發玩家的移動功能。
玩家轉動 (Q
/ E
):用 fPlayerA
控制角色方向,並搭配 chrono
套件,讓旋轉速率不受硬體 FPS 限制
玩家移動 (W
/ S
):透過 x = sinf(fPlayerA)
與 y = cosf(fPlayerA)
結合的單位向量,模擬角色向前走 / 後退
牆面渲染:不只是 #
,利用 short int
裝載16進位數字,裝載 ░▒▓█ 這些「漸層字元」,
讓遠近的牆有深淺之分,畫面更有立體感
到這裡,遊戲從一開始的「黑白畫布」,進化成一個能走能轉、還有陰影的「類 3D 世界」。
直接放一張 Demo 圖會很有感,角色站在 (8, 3),能轉動、能移動,
看到的牆會隨著遠近而變高、變暗:
「到目前為止,我們已經從單純的
wchar_t* screen
,發展成一個能探索迷宮的『類 3D 第一人稱遊戲』了!」
雖然目前的成果已經讓人小小感動,但我們還沒完工:
還需要優化 邊界處理,我們要真正地避免玩家走出世界的盡頭
以及處理地板的渲染
寫到第 24 天,其實每天都有新的「坑」出現,
一開始覺得是數學難、後來覺得是程式難,
但慢慢拆解後,卻越來越覺得好玩。
所以~還有很多東西要一起走下去~